package top.chenyaohua.visit;

import jdk.internal.org.objectweb.asm.*;
import top.chenyaohua.bean.MethodInfo;

import java.util.HashMap;
import java.util.Map;

public class PnuClassVisitor extends ClassVisitor {


    /**
     * 方法名
     */
    private MethodInfo methodInfo;

    private Map<String,PnuMethodVisitor> maps = new HashMap<>();

    public PnuClassVisitor ( ClassVisitor classVisitor) {
        super(327680, classVisitor);
    }

    public PnuClassVisitor (ClassVisitor cw, MethodInfo methodInfo) {
        super(327680, cw);
        this.methodInfo = methodInfo;
    }

    @Override
    public void visit (int i, int i1, String s, String s1, String s2, String[] strings) {
        System.out.println();
        super.visit(i, i1, s, s1, s2, strings);
    }

    @Override
    public void visitSource (String s, String s1) {
        super.visitSource(s, s1);
    }

    @Override
    public void visitOuterClass (String s, String s1, String s2) {
        super.visitOuterClass(s, s1, s2);
    }

    @Override
    public AnnotationVisitor visitAnnotation (String s, boolean b) {
        return super.visitAnnotation(s, b);
    }

    @Override
    public AnnotationVisitor visitTypeAnnotation (int i, TypePath typePath, String s, boolean b) {
        return super.visitTypeAnnotation(i, typePath, s, b);
    }

    @Override
    public void visitAttribute (Attribute attribute) {
        super.visitAttribute(attribute);
    }

    @Override
    public void visitInnerClass (String s, String s1, String s2, int i) {
        super.visitInnerClass(s, s1, s2, i);
    }

    @Override
    public FieldVisitor visitField (int i, String s, String s1, String s2, Object o) {
        return super.visitField(i, s, s1, s2, o);
    }

    @Override
    public MethodVisitor visitMethod (int i, String s, String s1, String s2, String[] strings) {
        Type[] params = Type.getArgumentTypes(s1);


        if( !s.equals(this.methodInfo.getMethodName().trim()) ||  ( params.length != methodInfo.getTypes().size() ) ){
            //如果参数个数不相同或者方法名不相同 直接返回
            return super.visitMethod(i, s, s1, s2, strings);
        }

        Boolean flag = Boolean.TRUE;

        //比较参数类型是否相同
        for (int j = 0; j < params.length; j++) {

            String type = methodInfo.getTypes().get(j).trim();
            String className = params[j].getClassName();

            flag &= className.equals(type);
        }

        if( flag ){

            switch (i){
                case 9:
                case 10:
                case 12:
                    //该方法为静态方法
                    this.methodInfo.setEnableStatic(true);
                    break;
                default:
                    this.methodInfo.setEnableStatic(false);
            }

            //如果参数类型、方法名、参数个数都相同
            PnuMethodVisitor pnuMethodVisitor = new PnuMethodVisitor(super.visitMethod(i, s, s1, s2, strings), params);


            maps.put(this.methodInfo.toString(),pnuMethodVisitor);
            return pnuMethodVisitor;
        }

        return super.visitMethod(i, s, s1, s2, strings);
    }

    @Override
    public void visitEnd () {
        super.visitEnd();
    }


    public Map<String, PnuMethodVisitor> getMaps () {
        return maps;
    }
}
